package com.zuo_book.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zuo_book.common.BusinessException;
import com.zuo_book.common.ResultCode;
import com.zuo_book.entity.SysProject;
import com.zuo_book.entity.SysProjectStage;
import com.zuo_book.entity.SysTemplateStage;
import com.zuo_book.mapper.SysProjectMapper;
import com.zuo_book.mapper.SysProjectStageMapper;
import com.zuo_book.mapper.SysTemplateStageMapper;
import com.zuo_book.service.SysProjectStageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 项目阶段服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysProjectStageServiceImpl implements SysProjectStageService {

    private final SysProjectStageMapper projectStageMapper;
    private final SysProjectMapper projectMapper;
    private final SysTemplateStageMapper templateStageMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createStage(SysProjectStage stage) {
        // 检查项目是否存在
        SysProject project = projectMapper.selectById(stage.getProjectId());
        if (project == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目不存在");
        }
        
        // 设置默认完成率
        if (stage.getCompletionRate() == null) {
            stage.setCompletionRate(0); // 默认为0%
        }
        
        // 插入阶段
        projectStageMapper.insert(stage);
        
        return stage.getId();
    }

    @Override
    public void updateStage(SysProjectStage stage) {
        // 检查阶段是否存在
        SysProjectStage existingStage = projectStageMapper.selectById(stage.getId());
        if (existingStage == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目阶段不存在");
        }
        
        // 更新阶段
        projectStageMapper.updateById(stage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteStage(Long stageId) {
        // 检查阶段是否存在
        SysProjectStage stage = projectStageMapper.selectById(stageId);
        if (stage == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目阶段不存在");
        }
        
        // 删除阶段
        projectStageMapper.deleteById(stageId);
    }

    @Override
    public SysProjectStage getStageById(Long stageId) {
        SysProjectStage stage = projectStageMapper.selectById(stageId);
        if (stage == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目阶段不存在");
        }
        return stage;
    }

    @Override
    public List<SysProjectStage> getProjectStages(Long projectId) {
        // 检查项目是否存在
        SysProject project = projectMapper.selectById(projectId);
        if (project == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目不存在");
        }
        
        // 查询项目阶段
        LambdaQueryWrapper<SysProjectStage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysProjectStage::getProjectId, projectId);
        wrapper.orderByAsc(SysProjectStage::getCreateTime);
        
        return projectStageMapper.selectList(wrapper);
    }

    @Override
    public Page<SysProjectStage> listProjectStages(Long projectId, int page, int size) {
        // 检查项目是否存在
        SysProject project = projectMapper.selectById(projectId);
        if (project == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目不存在");
        }
        
        // 创建分页对象
        Page<SysProjectStage> pageParam = new Page<>(page, size);
        
        // 构建查询条件
        LambdaQueryWrapper<SysProjectStage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysProjectStage::getProjectId, projectId);
        wrapper.orderByAsc(SysProjectStage::getCreateTime);
        
        // 执行查询
        return projectStageMapper.selectPage(pageParam, wrapper);
    }

    @Override
    public void updateStageCompletionRate(Long stageId, Integer completionRate) {
        // 检查阶段是否存在
        SysProjectStage stage = projectStageMapper.selectById(stageId);
        if (stage == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目阶段不存在");
        }
        
        // 检查完成率范围
        if (completionRate < 0 || completionRate > 100) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "完成率必须在0-100之间");
        }
        
        // 更新完成率
        SysProjectStage updateStage = new SysProjectStage();
        updateStage.setId(stageId);
        updateStage.setCompletionRate(completionRate);
        projectStageMapper.updateById(updateStage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int createStagesFromTemplate(Long projectId, Long templateId) {
        // 检查项目是否存在
        SysProject project = projectMapper.selectById(projectId);
        if (project == null) {
            throw new BusinessException(ResultCode.VALIDATE_FAILED.getCode(), "项目不存在");
        }
        
        // 查询模板阶段
        LambdaQueryWrapper<SysTemplateStage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysTemplateStage::getTemplateId, templateId);
        List<SysTemplateStage> templateStages = templateStageMapper.selectList(wrapper);
        
        if (templateStages.isEmpty()) {
            return 0;
        }
        
        // 创建项目阶段
        int count = 0;
        for (SysTemplateStage templateStage : templateStages) {
            SysProjectStage projectStage = new SysProjectStage();
            projectStage.setProjectId(projectId);
            projectStage.setStageName(templateStage.getStageName());
            projectStage.setWeight(templateStage.getWeight());
            projectStage.setCompletionRate(0); // 初始完成率为0
            
            projectStageMapper.insert(projectStage);
            count++;
        }
        
        return count;
    }
}